#pragma once

#include <algorithm>
#include <hash_map>
#include <vector>
#include "Next.h"


using namespace stdext;
using namespace std;

Next::Next(){
	Next::bitMapSetFlag = false;
}
Next::~Next(){
	Next::bitMapSetFlag = false;
	Next::nextRelation.clear();
	Next::revertNextRelation.clear();
}

bool Next::setNext(Type::Index::Line pred, Type::Index::Line succ){
	//insert to NextRelation
	if (Next::isNext(pred,succ)){
		return true;
	}
	if (nextRelation.find(pred) != nextRelation.end()){
		nextRelation.find(pred)->second.push_back(succ);
	}else{
		vector<Type::Index::Proc> listOfCalledProc;
		listOfCalledProc.push_back(succ);
		nextRelation[pred] = listOfCalledProc;
	}
	//insert to revertNextRelation
	if (revertNextRelation.find(succ) != revertNextRelation.end()){
		revertNextRelation.find(succ)->second.push_back(pred);
	}else{
		vector<Type::Index::Proc> listOfCallerProc;
		listOfCallerProc.push_back(pred);
		revertNextRelation[succ] = listOfCallerProc;
	}
	return true;
}
Type::List::Line Next::getSuccessor(Type::Index::Line pred){
	Type::List::Line succList;
	if (nextRelation.find(pred) != nextRelation.end()) {
		return nextRelation.find(pred)->second;
	} 
	return succList;
}
Type::List::Line Next::getPredecessor(Type::Index::Line succ){
	Type::List::Line predList;
	if (revertNextRelation.find(succ) != revertNextRelation.end()) {
		return revertNextRelation.find(succ)->second;
	} 
	return predList;
}
bool Next::isNext(Type::Index::Line p, Type::Index::Line s){
	if (bitMapSetFlag){
		return nextBitMap.at(p).at(s); 
	}else{
		Type::List::Line succList = getSuccessor(p);
		for (Type::List::Line::iterator iter = succList.begin(); iter!= succList.end(); ++iter){
			if (*iter == s){
				return true;
			}
		}
		return false;
	}
}
bool Next::hasSuccessor(Type::Index::Line p){
	if (nextRelation.find(p) == nextRelation.end()){
		return false;
	}else{
		return true;
	}
}
bool Next::hasPredecessor(Type::Index::Line s){
	if (revertNextRelation.find(s) == revertNextRelation.end()){
		return false;
	}else{
		return true;
	}
}
		
//return true if the bitMap is set correctly
bool Next::setNextBitMap(vector<vector<bool>> bitMap){
	if (bitMap.empty()){
		return Next::bitMapSetFlag;
	}else{
		int lineSize = bitMap.size();
		nextBitMap.resize(lineSize, vector<bool>(lineSize,false));
		for (int i=0; i<lineSize;i++){
			for (int j=0; j<lineSize;j++){
				nextBitMap.at(i).at(j) = bitMap.at(i).at(j);
			}
		}
		Next::bitMapSetFlag = true;
		return Next::bitMapSetFlag;
	}
}
bool Next::isBitMapSet(){
	return Next::bitMapSetFlag;
}